package com.hfh.learn;

/**
 * @Author hfh
 * @Date 2022 09 14 20 50
 **/
/*深拷贝把要复制的对象所有引用类型属性对应的对象取出来再次clone
拷贝的对象要实现Cloneable接口
把引用类型的属性克隆后在set到响应的属性中*/
public class Teacher implements Cloneable {
    private String name;
    private int age;
    private Address address;

    // 异常的处理方法, 在方法的末尾添加  throws Exception
    public static void main(String[] args) throws Exception {
        Teacher teacher = new Teacher();
        teacher.name = "赵四";
        teacher.age = 11;
        Address address = new Address();
        address.setDetail("合肥市, 蜀山区");
        teacher.address = address;

        Object obj = teacher.clone();
        Teacher cloneTea = (Teacher) obj;
        System.out.println(cloneTea.name);
        System.out.println(cloneTea.age);
        System.out.println(cloneTea.address.getDetail());


        // 深克隆, 克隆的引用数据类型指向不同的堆内存的地址值
        System.out.println(System.identityHashCode(teacher.address));//460141958
        System.out.println(System.identityHashCode(cloneTea.address));//1163157884

        // 深克隆后修改原对象里面的属性值, 就不会同步印象克隆的对象的属性值
        teacher.address.setDetail("合肥市, 滨湖区");
        System.out.println(cloneTea.address.getDetail());//合肥市, 蜀山区
        System.out.println(teacher.address.getDetail());//合肥市, 滨湖区
    }

    //    实现深克隆
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();
        Teacher teacher = (Teacher) obj;

        // 取出引用数据类型, 再次克隆
        Address address = teacher.address;
//        System.out.println(System.identityHashCode(address));
        // 克隆出来的Address就是一个新的对象
        Address newAddr = (Address) address.clone();
//        System.out.println(System.identityHashCode(newAddr));

        teacher.address = newAddr;
        return teacher;
    }
}
